package jp.dodododo.aop.interceptors;

import jp.dodododo.aop.HasTargetClass;
import jp.dodododo.aop.annotation.Enhance;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

/**
 * {@.en }
 * 
 * <br />
 * 
 * {@.ja メソッドの呼び出しをsynchronized化する{@link MethodInterceptor}です。}
 * 
 * @author Satoshi Kimura
 */
@Enhance(false)
public class SyncInterceptor extends AbstractMethodInterceptor {

	private static final SyncInterceptor INSTANCE = new SyncInterceptor();

	public static SyncInterceptor getInstance() {
		return INSTANCE;
	}

	/**
	 * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
	 */
	public Object invoke(MethodInvocation invocation) throws Throwable {
		Object target = invocation.getThis();
		if (target == null) {
			if (invocation instanceof HasTargetClass) {
				target = ((HasTargetClass) invocation).getTargetClass();
			} else {
				target = invocation.getMethod().getDeclaringClass();
			}
		}
		synchronized (target) {
			return invocation.proceed();
		}
	}

}
